package sudoku

import (
	"fmt"
	"math/rand"
)

type Level struct {
	Label string `json:"label"`
	Min   int    `json:"min"`
	Max   int    `json:"max"`
}

var Levels []Level = []Level{
	{"简单", 36, 41},
	{"普通", 42, 47},
	{"中等", 47, 51},
	{"困难", 52, 56},
	{"专家", 57, 62},
}

var vLen map[int]int = map[int]int{
	62: 10,
	61: 10,
	60: 20,
	59: 50,
	58: 100,
	57: 100,
}

func Generate(difficulty int) ([]int, []int, int) {
	solution := FullCells()

	level := Levels[difficulty]
	subject := EmptyCells()
	length := rand.Intn(level.Max-level.Min) + level.Min

	len, ok := vLen[length]
	if !ok {
		len = 10
	}

	for {
		if length < level.Min {
			break
		}

		for i := 0; i < len; i++ {
			subject = CloneCells(solution)
			ret := blank(subject, length)
			fmt.Println(`生成 [`, length, `] 空格`, i, ret)
			if ret {
				return solution, subject, length
			}
		}

		length--
	}

	return solution, subject, length
}

// 挖空单元格
func blank(cells []int, length int) bool {

	var indexes []int
	for i := 0; i < 81; i++ {
		indexes = append(indexes, i)
	}
	// rand.Seed(time.Now().UnixNano())
	rand.Shuffle(len(indexes), func(a, b int) {
		indexes[a], indexes[b] = indexes[b], indexes[a]
	})

	count := 0
	for i, index := range indexes {
		if count >= length {
			return true
		}

		if i > 20 {
			value := cells[index]
			cells[index] = 0

			ret := validate(cells)
			if ret {
				count++
			} else {
				cells[index] = value
				continue
			}
		} else {
			cells[index] = 0
			count++
		}
	}

	return count >= length
}

// 验证是否唯一解
func validate(cells []int) bool {
	return Solve(CloneCells(cells)) == 1
}
